﻿using System;
using System.Management;
using ClusterAwareProperties;
using ClusterAwareProperties.Properties;

namespace ClusterAwareProperties
{
    /// <summary>
    /// Wrapper class Node ManagementObject
    /// </summary>
    public class NodeProperty : IDisposable
    {
        #region private properties

        private readonly ManagementObject _classInstance;

        #endregion

        #region ctor

        /// <summary>
        /// Constructor
        /// </summary>
        private NodeProperty()
        {
            NameFormat = NameFormat.NotRulesmapped;
            PowerState = PowerState.Unknown;
            ResetCapability = NodeResetCapability.Unknown;
            Status = StatusResource.Unknown;
            State = NodeState.Unknown;
            Characteristics = CharacteristicsNode.Unknown;
        }

        /// <summary>
        /// Cosntructor
        /// </summary>
        /// <param name="queryobj">Node ManagementObject instance</param>
        public NodeProperty(ManagementObject queryobj)
            : this()
        {
            var path = queryobj.ToString();
            if (path.IndexOf("\\root\\MSCluster:MSCluster_Node") == -1)
            {
                throw new ClusterManagerException(string.Format(Resources.Error_TypeClassInvalid, path, "\\root\\MSCluster:MSCluster_Node"));
            }
            _classInstance = queryobj;
            this.Convert(queryobj);
        }

        #endregion

        #region public properties

        /// <summary>
        /// Return instance of Node ManagementObject
        /// </summary>
        public ManagementObject Instance
        {
            get { return _classInstance; }
        }

        /// <summary>
        /// Provides a short textual description (one-line string) of the node.
        /// </summary>
        public string Caption { get; internal set; }

        /// <summary>
        /// Indicates the name of the class or the subclass used in the creation of an instance. 
        /// When used with other key properties of the class, this property allows all instances of the class and its subclasses to be uniquely identified.
        /// </summary>
        public string CreationClassName { get; internal set; }

        /// <summary>
        /// Contains the data needed to find either the initial load device (its key) or the boot service to request the operating system to start up. 
        /// In addition, the load parameters (a path and parameters) may also be specified.
        /// </summary>
        public string[] InitialLoadInfo { get; internal set; }

        /// <summary>
        /// Indicates when the node was installed. 
        /// The lack of a value does not indicate that the node is not installed.
        /// </summary>
        public DateTime? InstallDate { get; internal set; }

        /// <summary>
        /// Contains the data identifying either the initial load device (its key) or the boot service that requested the last operating system load. 
        /// In addition, the load parameters (a path and parameters) may also be specified.
        /// </summary>
        public string LastLoadInfo { get; internal set; }

        /// <summary>
        /// Defines the label by which the node is known.
        /// </summary>
        public string Name { get; internal set; }

        /// <summary>
        /// Identifies how the node Name property is generated, using a heuristic. 
        /// This property identifies how the system name was generated by using the subclass heuristic. 
        /// The heuristic is outlined in the CIM V2 Common Model specification and assumes that the documented rules are traversed to determine and assign a name. 
        /// The NameFormat values list defines the precedence order for assigning the system name with several rules mapping to the same value.
        /// </summary>
        public NameFormat NameFormat { get; internal set; }

        /// <summary>
        /// Contains additional data, beyond the Name property, that can be used to identify a node.
        /// </summary>
        public string[] OtherIdentifyingInfo { get; internal set; }

        /// <summary>
        /// Provides explanations and details of the entries in the OtherIdentifyingInfo array. 
        /// Each entry of this array is related to the entry in OtherIdentifyingInfo is located at the same index.
        /// </summary>
        public string[] IdentifyingDescriptions { get; internal set; }

        /// <summary>
        /// NodeDedicated
        /// </summary>
        public NodeDedicated[] Dedicated { get; internal set; }

        /// <summary>
        /// Indicates the specific power-related capabilities of a node and its associated running operating system.
        /// </summary>
        public PowerCapacity[] PowerManagementCapabilities { get; internal set; }

        /// <summary>
        /// If TRUE, the node, with its running operating system, supports power management. 
        /// If FALSE, the integer value 1 ("Not Supported") should be the only entry in the PowerManagementCapabilities array. 
        /// This boolean does not indicate that power management features are currently enabled, or if enabled, what features are supported. 
        /// For more information, see the PowerManagementCapabilities array.
        /// </summary>
        public bool? PowerManagementSupported { get; internal set; }

        /// <summary>
        /// Indicates the current power state of the node and its associated operating system.
        /// </summary>
        public PowerState PowerState { get; internal set; }

        /// <summary>
        /// Provides information on how the primary system owner can be reached.
        /// </summary>
        public string PrimaryOwnerContact { get; internal set; }

        /// <summary>
        /// Contains the name of the primary node owner.
        /// </summary>
        public string PrimaryOwnerName { get; internal set; }

        /// <summary>
        /// Determines whether the node can be reset with the power and reset buttons.
        /// </summary>
        public NodeResetCapability ResetCapability { get; internal set; }

        /// <summary>
        /// An array of strings that specify the roles this node plays in the IT-environment.
        /// </summary>
        public string[] Roles { get; set; }

        /// <summary>
        /// status of node
        /// </summary>
        public StatusResource Status { get; internal set; }

        /// <summary>
        /// Provides access to the node's Description property, which has comments about the node.
        /// </summary>
        public string Description { get; set; }

        /// <summary>
        /// Provides access to the node's NodeHighestVersion property, which specifies the highest possible version of the cluster service with which the node can join or communicate.
        /// </summary>
        public UInt32 NodeHighestVersion { get; internal set; }

        /// <summary>
        /// Provides access to the node's NodeLowestVersion property, which specifies the lowest possible version of the cluster service with which the node can join or communicate.
        /// </summary>
        public UInt32 NodeLowestVersion { get; internal set; }

        /// <summary>
        /// Provides access to the node's MajorVersion property, which specifies the major portion of the Windows version installed.
        /// </summary>
        public UInt32 MajorVersion { get; internal set; }

        /// <summary>
        /// Provides access to the node's MinorVersion property, which specifies the minor portion of the Windows version installed.
        /// </summary>
        public UInt32 MinorVersion { get; internal set; }

        /// <summary>
        /// Provides access to the node's BuildNumber property.
        /// </summary>
        public UInt32 BuildNumber { get; internal set; }

        /// <summary>
        /// Provides access to the node's CSDVersion property, which specifies the most recent service pack installed on the node, if any.
        /// </summary>
        public UInt32 CsdVersion { get; internal set; }

        /// <summary>
        /// Provides access to the node's EnableEventLogReplication property.
        /// </summary>
        /// <remarks>
        /// This property is not supported in windows 2008
        /// </remarks>
        public UInt32? EnableEventLogReplication { get; set; }

        /// <summary>
        /// Specifies the instance of the node.
        /// </summary>
        public string NodeInstanceId { get; internal set; }

        /// <summary>
        /// Returns the current state of a node. For a list of possible state values, 
        /// see GetClusterNodeState or the CLUSTER_NODE_STATE enumeration.
        /// </summary>
        public NodeState State { get; set; }

        /// <summary>
        /// Provides access to the flags set for the node. For a list of possible characteristics, see CLUSCTL_NODE_GET_FLAGS.
        /// </summary>
        public UInt32 Flags { get; set; }

        /// <summary>
        /// Provides access to the characteristics set for the node. For a list of possible characteristics, see CLUSCTL_NODE_GET_CHARACTERISTICS.
        /// </summary>
        public CharacteristicsNode Characteristics { get; set; }

        /// <summary>
        /// CharacteristicsNode
        /// </summary>
        public PrivatePropertiesData PrivateProperties { get; set; }

        #endregion

        #region IDisposable Members

        /// <summary>
        /// Dispose Class
        /// </summary>
        public void Dispose()
        {
            if (Instance != null)
            {
                Instance.Dispose();
            }

        #endregion

        }
    }
}
